/*
 * Copyright 2011 TTOT
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package ttot.extensionmanager.api;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.List;

import com.google.inject.Injector;

import ttot.extension.api.ExtensionModule;
import ttot.extensionmanager.impl.Extension;

/**
 * ExtensionManager interface. Provides access to the major functionality of
 * this module.
 * 
 * @author bogdan@krax.ro
 * 
 */
public interface ExtensionManager {

	/**
	 * Loads extension classes wrapped in the provided {@link ByteBuffer}. The
	 * ByteBuffer should hold the jar package bytes where the extension classes
	 * are stored. This method converts the buffer in an input stream performs a
	 * call to the load(InputStream) method.
	 * 
	 * @param buffer
	 *            - the {@link ByteBuffer} that holds the extension jar package
	 *            bytes
	 */
	void load(ByteBuffer buffer) throws ExtensionManagerException;

	/**
	 * h Loads the extension classes read from the provided input stream. The
	 * stream should provided the bytes of the jar package that contains the
	 * extension classes.
	 * 
	 * @param inputStream
	 *            - the {@link InputStream} that provides the extension jar
	 *            package bytes
	 * @throws ExtensionManagerException
	 *             If the inputstream is null, or there are no available bytes
	 *             to read from the stream; wraps an {@link IOException} if
	 *             caught while reading the input stream; wraps an
	 *             {@link IOException} if caught while trying to close the
	 *             provided input stream
	 */
	void load(InputStream inputStream) throws ExtensionManagerException;

	/**
	 * Removes all Extensions stored by the ExtensionManager.
	 */
	void unload();

	/**
	 * Invokes {@link ExtensionModule.create} method on all known Extensions.
	 */
	void createExtensions() throws ExtensionManagerException;

	/**
	 * Invokes {@link ExtensionModule.destroy} method on all known Extensions.
	 */
	void destroyExtensions() throws ExtensionManagerException;

	/**
	 * Invokes {@link ExtensionModule.beforeTest} method on all known
	 * Extensions.
	 */
	void beforeTest() throws ExtensionManagerException;

	/**
	 * Invokes {@link ExtensionModule.afterTest} method on all known Extensions.
	 */
	void afterTest() throws ExtensionManagerException;

	/**
	 * Returns the list of extensions loaded by the {@link ExtensionManager}
	 * 
	 * @return {@link List<Extension>}
	 */
	List<Extension> getExtensions();

	/**
	 * Returns the injector created for all extension modules.
	 * 
	 * @return {@link Injector}
	 */
	Injector getExtensionInjector();

}
